
#include <BStream>
#include "member_BYamlNode.h"
#include "member_BYamlDocument.h"

using namespace BWE;

YamlFilter::YamlFilter(const BString& desc)
{
	BString str;
	int pos = 0;
	while (pos <= desc.size())
	{
		char ch = desc[pos];
		if (ch == '\"')
		{
			while (desc[++pos] != '\"')
				str.append(desc[pos]);
			pos++;
			continue;
		}
		if (ch == ':' || ch == '&' || ch == '|' || ch == 0)
		{
			if (str.size())
			{
				addInfo(str);
				str.reset();
			}
		}
		str.append(ch);
		pos++;
	}
}

void YamlFilter::addInfo(const BString& text)
{
	BString name;
	BString value;
	if (text.beginWith('='))
	{
		int equal_end = text.find('=');
		text.substr(name, 1, equal_end);
		text.substr(value, equal_end + 1);
		value.trimmed();
		return;
	}
	if (text.beginWith('&'))
	{
		includeTexts.append(text.cstr() + 1);
		return;
	}
	if (text.beginWith('|'))
	{
		excludeTexts.append(text.cstr() + 1);
		return;
	}
	name = text;
}

bool YamlFilter::operator()(BYamlNode* node) const
{
	if (name.size() && node->name() != name)
		return false;

	const BString& text = yaml_member(node)->text;
	for (int i = 0; i < includeTexts.size(); i++)
	{
		const BString& itext = includeTexts[i];
		if (!text.contain(itext))
			return false;
	}

	for (int i = 0; i < excludeTexts.size(); i++)
	{
		const BString& etext = excludeTexts[i];
		if (text.contain(etext))
			return false;
	}

	return true;
}

member_BYamlNode::member_BYamlNode(BYamlNode* sonNode)
{
	boss = sonNode;
	parent = 0;
	indent = 1;
}
member_BYamlNode::~member_BYamlNode()
{

}

BYamlNode* member_BYamlNode::find(YamlFilter& filter)
{
	if (filter(boss))
		return boss;
	for (int i = 0; i < children.size(); i++)
	{
		BYamlNode* child = children[i];
		BYamlNode* ret = yaml_member(child)->find(filter);
		if (ret)
			return ret;
	}
	return 0;
}
